package com.nobuyme.box.xunfei;

import android.media.AudioManager;
import android.media.AudioTrack;
import android.os.Handler;

public class PcmPlayer implements IPlayComplete{

	private final static String Tag 		 = "PcmPlayer";
	public  final static int 	STATE_MSG_ID = 0x0010;

	private Handler mHandler;
	private PcmParam   mPcmParam;							// 音频参数
	private byte[] 	   mData;								// 音频数据
	private AudioTrack mAudioTrack;							// AudioTrack对象
	private boolean    mBReady = false;						// 播放源是否就绪
	private PlayAudioThread mPlayAudioThread;				// 播放线程

	private boolean mThreadExitFlag = false;				// 线程退出标志
	private int     mPrimePlaySize = 0;						// 较优播放块大小
	private int 	mPlayOffset = 0;						// 当前播放位置
	private int     mPlayState = 0;							// 当前播放状态

	private OnStateChangedListener mOnStateChangedListener;

	public PcmPlayer(Handler handler) {
		mHandler = handler;
	}

	public PcmPlayer(Handler handler, PcmParam audioParam) {
		mHandler = handler;
		setPcmParam(audioParam);
	}

	/*
	 * 设置音频参数
	 */
	public void setPcmParam(PcmParam param) {
		mPcmParam = param;
	}

	/*
	 * 设置音频源
	 */
	public void setDataSource(byte[] data) {
		mData = data;
	}

	/*
	 *  就绪播放源
	 */
	public boolean prepare() {
		if (mData == null || mPcmParam == null) {
			return false;
		}

		if (mBReady == true) {
			return true;
		}

		try {
			createAudioTrack();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return false;
		}

		mBReady = true;

		setPlayState(PlayState.MPS_PREPARE);

		return true;
	}

	/*
	 * 释放播放源
	 */
	public boolean release() {
		stop();
		releaseAudioTrack();
		mBReady = false;
		setPlayState(PlayState.MPS_UNINIT);
		return true;
	}

	/*
	 * 播放
	 */
	public boolean play(OnStateChangedListener onStateChangedListener) {
		mOnStateChangedListener = onStateChangedListener;

		if (mBReady == false) {
			return false;
		}

		switch (mPlayState) {
            case PlayState.MPS_PREPARE:
                mPlayOffset = 0;
                setPlayState(PlayState.MPS_PLAYING);
                startThread();
                break;
            case PlayState.MPS_PAUSE:
                setPlayState(PlayState.MPS_PLAYING);
                startThread();
                break;
		}

		return true;
	}

	/*
	 * 暂停
	 */
	public boolean pause() {

		if (mBReady == false) {
			return false;
		}

		if (mPlayState == PlayState.MPS_PLAYING) {
			setPlayState(PlayState.MPS_PAUSE);
			stopThread();
		}

		return true;
	}

	/*
	 * 停止
	 */
	public boolean stop() {
		if (mBReady == false) {
			return false;
		}

		setPlayState(PlayState.MPS_PREPARE);
		stopThread();

		return true;
	}


	private synchronized void setPlayState(int state) {
		mPlayState = state;
		if (mOnStateChangedListener != null) {
            mOnStateChangedListener.onStateChanged(mPlayState);
        }
	}

	private void createAudioTrack() throws Exception {

		// 获得构建对象的最小缓冲区大小
		int minBufSize = AudioTrack.getMinBufferSize(mPcmParam.mFrequency,
													mPcmParam.mChannel,
													mPcmParam.mSampBit);

		mPrimePlaySize = minBufSize * 2;

		mAudioTrack = new AudioTrack(AudioManager.STREAM_MUSIC,
									mPcmParam.mFrequency,
									mPcmParam.mChannel,
									mPcmParam.mSampBit,
									minBufSize,
									AudioTrack.MODE_STREAM);
	}

	private void releaseAudioTrack() {
		if (mAudioTrack != null && mAudioTrack.getState() != AudioTrack.STATE_UNINITIALIZED &&
                mAudioTrack.getPlayState() != AudioTrack.PLAYSTATE_STOPPED) {
            try {
                mAudioTrack.stop();
            } catch (IllegalStateException e) {
                e.printStackTrace();
            }
			mAudioTrack.release();
			mAudioTrack = null;
		}

	}


	private void startThread() {
		if (mPlayAudioThread == null) {
			mThreadExitFlag = false;
			mPlayAudioThread = new PlayAudioThread();
			mPlayAudioThread.start();
		}
	}

	private void stopThread() {
		if (mPlayAudioThread != null) {
			mThreadExitFlag = true;
			mPlayAudioThread = null;
		}
	}

	/*
	 *  播放音频的线程
	 */
	class PlayAudioThread extends Thread {

		@Override
		public void run() {
			// TODO Auto-generated method stub
			if (mAudioTrack == null)
				return;

            try {
                mAudioTrack.play();
            } catch (IllegalStateException e) {
                e.printStackTrace();
                PcmPlayer.this.onPlayComplete();
                return;
            }

            while (true) {
                if (mThreadExitFlag == true) {
                    break;
                }

                try {
                    int size = mAudioTrack.write(mData, mPlayOffset,
                            (mData.length - mPlayOffset) > mPrimePlaySize ? mPrimePlaySize : mData.length - mPlayOffset);
                    mPlayOffset += size;
                } catch (Exception e) {
                    // TODO: handle exception
                    e.printStackTrace();
                    PcmPlayer.this.onPlayComplete();
                    break;
                }

                if (mPlayOffset >= mData.length) {
                    try {
                        sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    PcmPlayer.this.onPlayComplete();
                    break;
                }
            }
		}
	}

	@Override
	public void onPlayComplete() {
		// TODO Auto-generated method stub
		if (mPlayState != PlayState.MPS_PAUSE) {
			setPlayState(PlayState.MPS_COMPLETE);
		}
        release();
	}

	public interface OnStateChangedListener {
		public void onStateChanged(int state);
	}
}